#include "Subsystems/BlockBehaviors/SubsystemWaterBlockBehavior.h"
#include "Subsystems/SubsystemTerrain.h"
#include "Subsystems/SubsystemWeather.h"
#include "Subsystems/SubsystemTimeOfDay.h"

#include "Blocks/FluidBlock.h"
#include "Blocks/WaterBlock.h"
#include "Blocks/GraniteBlock.h"
#include "Blocks/MagmaBlock.h"

#include "Managers/BlocksManager.h"

#include "GameSingleton.h"

namespace PocketSurvival
{
    SubsystemWaterBlockBehavior::SubsystemWaterBlockBehavior() : SubsystemFluidBlockBehavior(true)  
    {
        m_handleBlocks.push_back(WaterBlock::Index());
    }

    bool SubsystemWaterBlockBehavior::onFluidInteract(int32_t interactValue, int32_t x, int32_t y, int32_t z, int32_t fluidValue)
    {
		if (GameSingleton::blocksManager->blocks[Terrain::ExtractContents(interactValue)]->isBlock<MagmaBlock*>() == true)
		{
            subsystemTerrain->destroyCell(0, x, y, z, 0, false);
			set(x, y, z, GraniteBlock::Index());
			return true;
		}
		return SubsystemFluidBlockBehavior::onFluidInteract(interactValue, x, y, z, fluidValue);
    }

    void SubsystemWaterBlockBehavior::onItemHarvested(int32_t x, int32_t y, int32_t z, int32_t blockValue, BlockDropValue &outDropValue, int32_t &outNewBlockValue)
    {
		if (y > 150 && SubsystemWeather::IsPlaceFrozen(subsystemTerrain->getTemperature(x, z), y))
		{
			outDropValue.value = Terrain::MakeBlockValue(62);
		}
		else
		{
			SubsystemFluidBlockBehavior::onItemHarvested(x, y, z, blockValue, outDropValue, outNewBlockValue);
		}
    }



    void SubsystemWaterBlockBehavior::update(float dt)
    {
        if(m_timeOfDay->periodicGameTimeEvent(0.25, 0.0))
        {
            spreadFluid();
        }
    }

    void SubsystemWaterBlockBehavior::load(const nlohmann::json& json)
    {
        SubsystemFluidBlockBehavior::load(json);
        m_timeOfDay = GameSingleton::singletonPtr->getSingleton<SubsystemTimeOfDay>();
        m_fluidBlock = GameSingleton::blocksManager->blocks[WaterBlock::Index()]->asBlock<FluidBlock*>();
        m_fluidType = FluidType::Water;
    }

    static const std::string subsystemName = "WaterBlockBehavior";
    const std::string& SubsystemWaterBlockBehavior::getName() const
    {
        return subsystemName;
    }
    SubUpdateType SubsystemWaterBlockBehavior::getUpdateType()
    {
        return SubUpdateType::MultiThreadUpdate;
    }
    
} // namespace PocketSurvival
